{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# C++ Qt 学习问题和解决\n",
    "\n",
    "下一个项目中大概率需要使用C/C++开发，所以现在正在努力学C++ Qt。不知道会不会有版权问题。。。\n",
    "在一个入门项目，写一个简单的NOTEPAD的demo中，有遇到不少问题，记录下来。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## MyNotePad项目\n",
    "\n",
    "### 1. cpp主要文件中关于mainwindow类的声明\n",
    "在头文件中声明了这个APP继承的是 QMainWiondow， 但是在对应的cpp文件中， 类的声明变成了这样：     \n",
    "```c++\n",
    "// .h\n",
    "class MainWindow : public QMainWindow\n",
    "\n",
    "// .cpp\n",
    "MainWindow::MainWindow()\n",
    "    : textEdit(new QPlainTextEdit)\n",
    "```\n",
    "不知道为啥会有个textEdit，且代码中只是直接将textEdit设置为中心位置的组件而已，难道在声明的时候都已经生成了实体对象吗？？？\n",
    "\n",
    "**解答：**     \n",
    "\n",
    "网上也有人问， 但是回答依然不够明确，这是解答最开始生成的代码：\n",
    "```c++\n",
    "MainWindow::MainWindow(QWidget *parent) :\n",
    "QMainWindow(parent)\n",
    "```\n",
    "> 这是 C++ 的继承的语法的一部分，说明 MainWindow 的构造函数之前需要调用父类 QMainWindow 的带有参数的构造函数。类似于 Java 的 super()。\n",
    "\n",
    "再看一次好像有点明白了，这句话的意思就是在头文件声明的类：MainWindow的作用域下的构造函数为 MainWindow()， 后面加引号加 textEdit(new QPlainTextEdit)这个写法，查了以后，意思就是：\n",
    "```c++\n",
    "MainWindow::MainWindow(){\n",
    "    textEdit = new QPlainTextEdit();\n",
    "}\n",
    "```\n",
    "这语法真反人类，self也没有，this也没有，意味着自带的属性的名字不能和传入的参数相同了。。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. (tr(\"&File\")) tr是什么意思\n",
    "之前写pyqt也有见到过这个，一直不知道是什么意思。 这个项目中又看到了：\n",
    "```\n",
    "QMenu *fileMenu = menuBar()->addMenu(tr(\"&File\"));\n",
    "```\n",
    "查了一下，貌似是国际化的意思。 学习了这个博客的国际化，忽然觉得Qt好香，做的真好。。   \n",
    "\n",
    "https://blog.csdn.net/li1123576747/article/details/109383949?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1.control    \n",
    "\n",
    "有专门的翻译工具，我之前做国际化都是自己手写。。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 退出程序前调用setGeometry()\n",
    "这个是用来保存窗体的位置，大小的状态的函数。  在画好界面后可以调用加载配置的函数，可以加载上一次的窗体状态。 \n",
    "```c++\n",
    "void MainWindow::readSettings()\n",
    "//! [34] //! [36]\n",
    "{\n",
    "    QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());\n",
    "    const QByteArray geometry = settings.value(\"geometry\", QByteArray()).toByteArray();\n",
    "    if (geometry.isEmpty()) {\n",
    "        const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);\n",
    "        resize(availableGeometry.width() / 3, availableGeometry.height() / 2);\n",
    "        move((availableGeometry.width() - width()) / 2,\n",
    "             (availableGeometry.height() - height()) / 2);\n",
    "    } else {\n",
    "        restoreGeometry(geometry);\n",
    "    }\n",
    "}\n",
    "```\n",
    "\n",
    "写入窗体配置的函数： \n",
    "```c++\n",
    "void MainWindow::writeSettings()\n",
    "//! [37] //! [39]\n",
    "{\n",
    "    QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());\n",
    "    settings.setValue(\"geometry\", saveGeometry());\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MFC问题\n",
    "\n",
    "大概可能也许不能用QT，用MFC，那就很难受了，这个框架比较老 语法风格不好看导致理解速度慢而且很不方便。。VS2010。。 吐了。\n",
    "\n",
    "## 1. inline内联函数\n",
    "在 c/c++ 中，为了解决一些频繁调用的小函数大量消耗栈空间（栈内存）的问题，特别的引入了 inline 修饰符，表示为内联函数。栈空间就是指放置程序的局部数据（也就是函数内数据）的内存空间。   \n",
    "\n",
    "inline 函数仅仅是一个对编译器的建议，所以最后能否真正内联，看编译器的意思，它如果认为函数不复杂，能在调用点展开，就会真正内联，并不是说声明了内联就会内联，声明内联只是一个建议而已。 （啊这？？？？）\n",
    "\n",
    "inline 的使用是有所限制的，inline 只适合涵数体内代码简单的涵数使用，不能包含复杂的结构控制语句例如 while、switch，并且不能内联函数本身不能是直接递归函数（即，自己内部还调用自己的函数）。\n",
    "\n",
    "其次，因为内联函数要在调用点展开，所以编译器必须随处可见内联函数的定义，要不然就成了非内联函数的调用了。所以，这要求每个调用了内联函数的文件都出现了该内联函数的定义。\n",
    "\n",
    "因此，将内联函数的定义放在头文件里实现是合适的，省却你为每个文件实现一次的麻烦。   \n",
    "\n",
    "讲道理，既然编译器会自动判断，那用内联干啥？谁会听别人的建议呢？\n",
    "\n",
    "\n",
    "## 2. 消息映射 BEGIN_MESSAGE_MAP\n",
    "在使用消息映射之前必须声明：DECLARE_MESSAGE_MAP()， 只要当前类是CCmdTarget派生的，则必须提供消息映射以处理消息。\n",
    "具体方式是在类或者结构体末尾添加DECLARE_MESSAGE_MAP（无分号），然后在定义类成员函数的.CPP文件中，使用BEGIN_MESSAGE_MAP（）和END_MESSAGE_MAP（）宏来实现对消息的处理。    \n",
    "\n",
    "```c++\n",
    "#define DECLARE_MESSAGE_MAP() \n",
    "private: \n",
    "\tstatic const AFX_MSGMAP_ENTRY _messageEntries[]; \n",
    "protected: \n",
    "\tstatic AFX_DATA const AFX_MSGMAP messageMap; \n",
    "\tstatic const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); \n",
    "\tvirtual const AFX_MSGMAP* GetMessageMap() const;\n",
    "```\n",
    "声明添加了两个成员变量和两个成员函数：\n",
    "\n",
    "_messageEntries: 是一个AFX_MSGMAP_ENTRY（定义了消息路由）类型数组，即路由表。      \n",
    "messageMap： 路由信息，包含父类路由信息指针，和本类的路由表指针。\n",
    "\n",
    "```c++\n",
    "struct AFX_MSGMAP_ENTRY\n",
    "{\n",
    "\tUINT nMessage;    //消息类型\n",
    "\tUINT nCode;       // 控制码\n",
    "\tUINT nID;         // 控件ID\n",
    "\tUINT nLastID;      // 控件ID范围, 对于单控件消息处理，与nID相同\n",
    "\tUINT nSig;         // 信号类型\n",
    "\tAFX_PMSG pfn;    //回调函数，即处理函数\n",
    "};\n",
    "\n",
    "\n",
    "struct AFX_MSGMAP\n",
    "{\n",
    "\tconst AFX_MSGMAP* pBaseMap;\t\t//指向父类的指针\n",
    "\tconst AFX_MSGMAP_ENTRY* lpEntries;\t//路由表指针\n",
    "};\n",
    "```\n",
    "em...没看懂，这特么跟路由表有什么关系，全是宏。。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.在MFC中使用cout\n",
    "由于链接的原因，不能直接在MFC中使用cout输出数据。 。 找到一篇文章提到的方法，经过测试可以：\n",
    "1. 在.h文件中插入： \n",
    "```c++\n",
    "#include <io.h>  \n",
    "#include <fcntl.h> \n",
    "```\n",
    "2. 在public中插入：\n",
    "```c++\n",
    "bool OpenConsole();\n",
    "```\n",
    "\n",
    "3. 在对应的cpp文件中加上：\n",
    "```c++\n",
    "#include<iostream>\n",
    "using namespace std;\n",
    "```\n",
    "\n",
    "4. 并实现函数OpenConsole():\n",
    "```c++\n",
    "bool CmultiFuncDlg::OpenConsole()\n",
    "{\n",
    "\t// 保证函数只执行一次\n",
    "\tstatic bool Runed = false;\n",
    "\tif (Runed)\n",
    "\t\treturn false;\n",
    "\tRuned = true;\n",
    " \n",
    "\tbool result;\n",
    "\tHANDLE hStd;\n",
    "\tFILE* fp;\n",
    "\tlong hFile;\n",
    " \n",
    "\tresult = AllocConsole();\n",
    "\thStd = GetStdHandle(STD_INPUT_HANDLE);\n",
    "\thFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);\n",
    "\tfp = _fdopen(hFile, \"r\");\n",
    "\t(*stdin) = (*fp);\n",
    " \n",
    "\thStd = GetStdHandle(STD_OUTPUT_HANDLE);\n",
    "\thFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);\n",
    "\tfp = _fdopen(hFile, \"w\");\t// 注意：必须是可写模式\n",
    "\t(*stdout) = (*fp);\n",
    " \n",
    "\thStd = GetStdHandle(STD_ERROR_HANDLE);\n",
    "\thFile = (long)_open_osfhandle((intptr_t)hStd, _O_TEXT);\n",
    "\tfp = _fdopen(hFile, \"w\");\t// 注意：必须是可写模式\n",
    "\t(*stderr) = (*fp);\n",
    "  \n",
    "\tcout << \"打开控制台成功\" << endl;\n",
    " \n",
    "\treturn result;\n",
    "}\n",
    "\n",
    "```\n",
    "\n",
    "5. 在程序必经之路：OnInitDialog()中调用OpenConsole()即可。\n",
    "\n",
    "### 3. MFC程序提示 0xC0000005: 读取位置 0x00000020 时发生访问冲突\n",
    "意思就是 EXCEPTION_NULL_POINTER。 有空指针。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 记一次奇怪的BUG，接收数据有时候数据错误\n",
    "\n",
    "在测量钢筋的项目中，我负责维护北京写过来的程序，现在要加一个新的功能，接收新的位移数据。 位移数据有2个字节，最后结果是 第一个字节x256+第二个字节。 \n",
    "一开始的写法是这样，没有问题， 之后换了一块板子，问题就来了。\n",
    "\n",
    "![5616faa761ae150db18fee76b5dfe1e.png](attachment:5616faa761ae150db18fee76b5dfe1e.png)![image.png](attachment:image.png)\n",
    "\n",
    "具体表现为： \n",
    "在位移到某些固定的数时，数据会解析错误，比如从-26.5突然变成-36.2之类的，由于MFC DEBUG不是很方便，查了文章后，使用了TRACE作为线程里DEBUG的工具。  \n",
    "```c++\n",
    "TRACE(\"Get shift: %x, %x, %d, %d\\n\", m_sRebarData.chShift[0], m_sRebarData.chShift[1], m_sRebarData.chShift[0]*256, m_sRebarData.chShift[1]); \n",
    "```\n",
    "打印出来的部分数据：\n",
    "![](C++bug.png)\n",
    "\n",
    "多次测试后，发现在第二位数超过128时，会自动右移8位，比如 8B=1000 1011=139，在程序里体现为：FF8B=1111 1111 1000 1011=-117。 \n",
    "刚开始不太确定原因，对底层也不太熟悉，走了几个弯路。\n",
    "1. 修改接收的类型为 short。 结果：错误， 解析的数据会多出两位，把尾部的字节也作为数据解析了。 \n",
    "2. 考虑如果接到的数据为128的倍数，第二位乘以-1，强行变成整数。 结果：错误，我很快意识到这是位移的问题，即使变成正数也是错误的正数。\n",
    "3. 既然只有char类型解析的长度是正确的，根据2，我发现第一位也数的解析也一直是正确的情况下，那么就是第二位的问题，遇到128会溢出变成负数，就是十六进制的80， 反过来， 2位十六进制能表示的最大数是255也就是FF，刚好就是unsigned char能表示的最大数。 所以， 第二位会不会是unsigned char而不是char类型。 我试了一下， 结果： 正确。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.5403023058681398+0.8414709848078965j)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "n = 10;\n",
    "fn = np.linspace(0, 9, 9)\n",
    "w=np.exp(1j)\n",
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "metadata": {},
   "outputs": [],
   "source": [
    "def invczt(X,F,T1,T2,n,flag,s):\n",
    "   # X 输入点\n",
    "   # F 长度为2的列表， F0： 起始频率， F1：终止频率  1*10^9,2.4*10^9\n",
    "   # T1/T2: 起始时间，终止时间 0，1*10^-8\n",
    "   # n 点数\n",
    "   # flag： 加窗的标志位（设置为1）\n",
    "   # s: 窗参数 \n",
    "    delta_F=F[1]-F[0]\n",
    "    \n",
    "    delta_t=(T2-T1)/n\n",
    "    print(\"deltaF/T: \" + str(delta_F) + \"/\" + str(delta_t))\n",
    "\n",
    "    w=np.exp(-1*1j*2*np.pi*delta_t*delta_F)\n",
    "    print(\"w: \"+ str(w))\n",
    "    a=np.exp(1j*2*np.pi*T1*delta_F)\n",
    "    print(\"a: \" + str(a))\n",
    "    t=np.linspace(T1,T2,n)\n",
    "    print(\"t linspace:\" + str(t[0:3]))\n",
    "    print(\"end======================\")\n",
    "    \n",
    "    yres = czt(np.conj(X),n,w,a)\n",
    "#     print(\"temp check: \")\n",
    "#     print((np.exp(1j * 2 * np.pi * F[1] * t))[0:10])\n",
    "#     print()\n",
    "    Y = 2 * np.conj(czt(np.conj(X), n, w, a)) * np.exp(1j * 2 * np.pi * F[1] * t) / len(X)\n",
    "    print(\"Y length:\" + str(len(Y)))\n",
    "    print(\"Y head 10: \" + str(Y[0:10]))\n",
    "    \n",
    "#     return Y,t\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "deltaF/T: 1400000000.0/3.90625e-11\n",
      "w: (0.9415440651830208-0.33688985339222005j)\n",
      "a: (1+0j)\n",
      "t linspace:[0.00000000e+00 3.92156863e-11 7.84313725e-11]\n",
      "end======================\n",
      "[0.  0.5 2.  4.5]\n",
      "[-20000.  -19800.5 -19602.  -19404.5]\n",
      "[0.  0.5 2.  4.5]\n",
      "\n",
      "xx lenght: 201\n",
      "xx head 10: [ 0.        +0.j          0.09510853-0.03680174j  0.12922636-0.15779907j\n",
      " -0.05261956-0.30138212j -0.40016649-0.07916301j -0.11119968+0.49762901j\n",
      "  0.60887289-0.06061188j -0.49277783-0.51649783j  0.16      +0.8j\n",
      "  0.02156473-0.91757014j]\n",
      "\n",
      "fxx length: 512\n",
      "fxx head 10: [ 163.58274215+125.0962921j    57.62206429-161.27727072j\n",
      " -122.10335268 +52.06897997j  139.82008317 +78.74071419j\n",
      "   54.33305814-162.02333258j -127.88771531 -55.41802653j\n",
      "  -81.19032788 +81.97528752j   56.57867295+121.66070798j\n",
      "  146.41648623 -50.08808075j  -49.83898059-116.47720721j]\n",
      "\n",
      "ww length: 456\n",
      "ww head 10: [-5.60990366e-13-1.00000000e+00j  5.34997620e-01-8.44853565e-01j\n",
      "  9.95184727e-01-9.80171403e-02j  4.05241314e-01+9.14209756e-01j\n",
      " -9.23879533e-01+3.82683432e-01j -2.45412285e-02-9.99698819e-01j\n",
      "  7.73010453e-01+6.34393284e-01j -9.85277642e-01-1.70961889e-01j\n",
      "  1.00000000e+00+9.41717185e-14j -9.85277642e-01-1.70961889e-01j]\n",
      "fww length: 512\n",
      "fww head 10: [ 2.87747357e+01-2.91822449e+01j -2.09037915e+00+7.77646593e-01j\n",
      "  1.91979765e-12-7.99360578e-13j  2.10016311e+00+7.50822318e-01j\n",
      " -3.36719967e+01-2.33620520e+01j  3.19648032e+00+5.07779895e+00j\n",
      "  1.76729583e+00+7.04692046e+00j -4.37018620e-01+8.00457787e+00j\n",
      "  3.22822893e+01-2.09020469e+01j -4.43640934e+00+6.75567751e+00j]\n",
      "\n",
      "fyy length: 512\n",
      "fyy head 10: [ 8.35764081e+03-1.17409891e+03j  4.96475821e+00+3.81940247e+02j\n",
      " -1.92791840e-10+1.97566512e-10j  2.34524695e+02+2.70348382e+02j\n",
      " -5.61470008e+03+4.18631738e+03j -1.27388969e+02-8.26530738e+02j\n",
      " -7.21160659e+02-4.27267200e+02j -9.98568544e+02+3.99720398e+02j\n",
      "  3.67971595e+03-4.67736218e+03j  1.00798857e+03+1.80044490e+02j]\n",
      "yy length: 512\n",
      "yy head 10: [-34.75684434+14.43936887j -23.05355825-18.21525557j\n",
      "  -4.74482978-24.69370089j  11.12632057 -0.31076086j\n",
      "   1.12360542+16.41667514j  -7.64858977-10.59531664j\n",
      "   8.00021663 +1.90578748j  -7.13378245 +2.10626051j\n",
      "   7.2        -1.44j        -7.73083333 -3.69241624j]\n",
      "\n",
      "Catch yy length: 256\n",
      "yy head 10: [ 2.01000000e+03-402.j         -1.16339553e+01 +58.85231269j\n",
      " -2.44279190e+01 +18.16712841j -1.88215703e+01  -8.86837569j\n",
      "  4.66769508e+00 -15.47582628j  1.19533089e+01  +6.3628524j\n",
      " -1.02410952e+01  +6.16380707j  3.68135628e+00 -10.35197074j\n",
      "  2.12719874e-02 +10.44980304j -2.16855711e-02 -10.24991903j]\n",
      "\n",
      "y Result head 10:[ 2.01000000e+03-4.02000000e+02j -1.40117355e+00+5.99748309e+01j\n",
      " -7.35793252e+00+2.95402880e+01j -9.32760916e+00+1.85982608e+01j\n",
      " -1.02347303e+01+1.25115496e+01j -1.06609563e+01+8.34934095e+00j\n",
      " -1.07959402e+01+5.13032379e+00j -1.07154162e+01+2.42807273e+00j\n",
      " -1.04498030e+01+2.12719874e-02j -1.00056192e+01-2.22461131e+00j]\n",
      "temp check: \n",
      "[ 1.        +0.j          0.83018403+0.55748944j  0.37841105+0.92563766j\n",
      " -0.20188241+0.97940977j -0.71361015+0.70054304j -0.9829731 +0.18374952j\n",
      " -0.91848699-0.39545121j -0.54205336-0.84034407j  0.0184789 -0.99982925j\n",
      "  0.57273514-0.81974048j]\n",
      "\n",
      "[0.  0.5 2.  4.5]\n",
      "[-20000.  -19800.5 -19602.  -19404.5]\n",
      "[0.  0.5 2.  4.5]\n",
      "\n",
      "xx lenght: 201\n",
      "xx head 10: [ 0.        +0.j          0.09510853-0.03680174j  0.12922636-0.15779907j\n",
      " -0.05261956-0.30138212j -0.40016649-0.07916301j -0.11119968+0.49762901j\n",
      "  0.60887289-0.06061188j -0.49277783-0.51649783j  0.16      +0.8j\n",
      "  0.02156473-0.91757014j]\n",
      "\n",
      "fxx length: 512\n",
      "fxx head 10: [ 163.58274215+125.0962921j    57.62206429-161.27727072j\n",
      " -122.10335268 +52.06897997j  139.82008317 +78.74071419j\n",
      "   54.33305814-162.02333258j -127.88771531 -55.41802653j\n",
      "  -81.19032788 +81.97528752j   56.57867295+121.66070798j\n",
      "  146.41648623 -50.08808075j  -49.83898059-116.47720721j]\n",
      "\n",
      "ww length: 456\n",
      "ww head 10: [-5.60990366e-13-1.00000000e+00j  5.34997620e-01-8.44853565e-01j\n",
      "  9.95184727e-01-9.80171403e-02j  4.05241314e-01+9.14209756e-01j\n",
      " -9.23879533e-01+3.82683432e-01j -2.45412285e-02-9.99698819e-01j\n",
      "  7.73010453e-01+6.34393284e-01j -9.85277642e-01-1.70961889e-01j\n",
      "  1.00000000e+00+9.41717185e-14j -9.85277642e-01-1.70961889e-01j]\n",
      "fww length: 512\n",
      "fww head 10: [ 2.87747357e+01-2.91822449e+01j -2.09037915e+00+7.77646593e-01j\n",
      "  1.91979765e-12-7.99360578e-13j  2.10016311e+00+7.50822318e-01j\n",
      " -3.36719967e+01-2.33620520e+01j  3.19648032e+00+5.07779895e+00j\n",
      "  1.76729583e+00+7.04692046e+00j -4.37018620e-01+8.00457787e+00j\n",
      "  3.22822893e+01-2.09020469e+01j -4.43640934e+00+6.75567751e+00j]\n",
      "\n",
      "fyy length: 512\n",
      "fyy head 10: [ 8.35764081e+03-1.17409891e+03j  4.96475821e+00+3.81940247e+02j\n",
      " -1.92791840e-10+1.97566512e-10j  2.34524695e+02+2.70348382e+02j\n",
      " -5.61470008e+03+4.18631738e+03j -1.27388969e+02-8.26530738e+02j\n",
      " -7.21160659e+02-4.27267200e+02j -9.98568544e+02+3.99720398e+02j\n",
      "  3.67971595e+03-4.67736218e+03j  1.00798857e+03+1.80044490e+02j]\n",
      "yy length: 512\n",
      "yy head 10: [-34.75684434+14.43936887j -23.05355825-18.21525557j\n",
      "  -4.74482978-24.69370089j  11.12632057 -0.31076086j\n",
      "   1.12360542+16.41667514j  -7.64858977-10.59531664j\n",
      "   8.00021663 +1.90578748j  -7.13378245 +2.10626051j\n",
      "   7.2        -1.44j        -7.73083333 -3.69241624j]\n",
      "\n",
      "Catch yy length: 256\n",
      "yy head 10: [ 2.01000000e+03-402.j         -1.16339553e+01 +58.85231269j\n",
      " -2.44279190e+01 +18.16712841j -1.88215703e+01  -8.86837569j\n",
      "  4.66769508e+00 -15.47582628j  1.19533089e+01  +6.3628524j\n",
      " -1.02410952e+01  +6.16380707j  3.68135628e+00 -10.35197074j\n",
      "  2.12719874e-02 +10.44980304j -2.16855711e-02 -10.24991903j]\n",
      "\n",
      "y Result head 10:[ 2.01000000e+03-4.02000000e+02j -1.40117355e+00+5.99748309e+01j\n",
      " -7.35793252e+00+2.95402880e+01j -9.32760916e+00+1.85982608e+01j\n",
      " -1.02347303e+01+1.25115496e+01j -1.06609563e+01+8.34934095e+00j\n",
      " -1.07959402e+01+5.13032379e+00j -1.07154162e+01+2.42807273e+00j\n",
      " -1.04498030e+01+2.12719874e-02j -1.00056192e+01-2.22461131e+00j]\n",
      "Y length:256\n",
      "Y head 10: [ 2.00000000e+01+4.j          3.21115452e-01-0.50319688j\n",
      "  2.44370946e-01-0.17899653j  1.99984064e-01-0.05354119j\n",
      "  1.59885437e-01+0.01749751j  1.19538514e-01+0.06217146j\n",
      "  7.84789838e-02+0.0893672j   3.74916499e-02+0.10269434j\n",
      " -2.13302759e-03+0.10395647j -3.88752810e-02+0.09428979j]\n"
     ]
    }
   ],
   "source": [
    "X = []\n",
    "for i in range(201):\n",
    "    X.append(i*0.1+i*0.02j)\n",
    "#X = np.ones([100])\n",
    "F = [1e9, 2.4e9]\n",
    "invczt(X,F, 0, 1e-8, 256, 1, 0.2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "metadata": {},
   "outputs": [],
   "source": [
    "def czt(x, m = None, w = None, a = None):\n",
    "    n = len(x)\n",
    "\n",
    "    if m is None: m = n\n",
    "    if w is None: w = np.exp(-2j * np.pi / m)\n",
    "    if a is None: a = 1\n",
    "\n",
    "    wExponents1 =   np.arange(    0   , n) ** 2 / 2.0    # n elements         [ 0 .. (n - 1) ]\n",
    "    print(wExponents1[0:4])\n",
    "    wExponents2 = - np.arange(-(n - 1), m) ** 2 / 2.0    # m + n - 1 elements [ -(n - 1) .. +(m - 1) ]\n",
    "    print(wExponents2[0:4])\n",
    "    wExponents3 =   np.arange(    0   , m) ** 2 / 2.0    # m elements         [ 0        ..  (m - 1) ]\n",
    "    print(wExponents3[0:4])\n",
    "    print()\n",
    "    xx = x * a ** -np.arange(n) * w ** wExponents1\n",
    "    print(\"xx lenght: \" + str(len(xx)))\n",
    "    print(\"xx head 10: \" + str(xx[0:10]))\n",
    "    print()\n",
    "    # Determine next-biggest FFT of power-of-two\n",
    "    nfft = 1\n",
    "    while nfft < (m + n - 1):\n",
    "        nfft += nfft\n",
    "    fxx = np.fft.fft(xx, nfft)\n",
    "    print(\"fxx length: \" + str(len(fxx)))\n",
    "    print(\"fxx head 10: \"+ str(fxx[0:10]))\n",
    "    print()\n",
    "    \n",
    "    ww = w ** wExponents2\n",
    "    print(\"ww length: \" + str(len(ww)))\n",
    "    print(\"ww head 10: \" + str(ww[0:10]))\n",
    "    fww = np.fft.fft(ww, nfft)\n",
    "    print(\"fww length: \" + str(len(fww)))\n",
    "    print(\"fww head 10: \"+ str(fww[0:10]))\n",
    "    print()\n",
    "    \n",
    "    fyy = fxx * fww\n",
    "    print(\"fyy length: \" + str(len(fyy)))\n",
    "    print(\"fyy head 10: \" + str(fyy[0:10]))\n",
    "    yy = np.fft.ifft(fyy, nfft)\n",
    "    print(\"yy length: \" + str(len(yy)))\n",
    "    print(\"yy head 10: \"+ str(yy[0:10]))\n",
    "    print()\n",
    "    # select output\n",
    "    yy = yy[n - 1 : m + n - 1]\n",
    "    y = yy * w ** wExponents3\n",
    "    print(\"Catch yy length: \" + str(len(yy)))\n",
    "    print(\"yy head 10: \" + str(yy[0:10]))\n",
    "    print()\n",
    "    print(\"y Result head 10:\" + str(y[0:10]))\n",
    "    return y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-4, -1,  0, -1, -4], dtype=int32)"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "-np.arange(-2, 3)**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.25"
      ]
     },
     "execution_count": 99,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2**-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
